#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
from string import atoi,atof
from ClusterUtility import dotproduct

_DEBUG = False
#_DEBUG = True

"""
@desc :采用感知器法对数据进行分类
@data :数据样品
@C :参数，控制迭代
"""
def PerceptronClassifier(dataset, C):
    #初始化权值向量
    weight = [0] * len(dataset[0]);
    while 1:
        print("iter...")
        flag = True
        for data in dataset:
            #不可使下面的判断条件为<=0，因为数据中可能存在全为0的属性样品，如此在这一轮中weight的值不变，但是仍然满足下面的判断条件，造成死循环
            if dotproduct(weight, data) <= 0:
                flag = False
                #修改权值
                for i in range(0, len(data)):
                    weight[i] = weight[i] + C * data[i]
                print(weight); #tmp = raw_input()
        if flag:
            break
    print("训练结果：")
    print(weight)
# 初始化参数和训练数据
def init(argv):
    if len(argv) < 2:
        print("Usage: python Perceptron.py <train-file> -C <value>")
        return 
    else:
        filepath = argv[1]
        print("数据文件：" + filepath)
        # 解析参数C
        for i in range(2,len(argv)):
            if "-C" == argv[i]:
                if i+1 < len(argv):
                    C = atof(argv[i+1])
                    i = i + 1
                else:
                    print("-C <value> : <value> can't be empty!")
                    exit(1)
        print("C = %d" % C)
    #从数据文件中读取样品数据
    f = open(filepath,"r") #open data file
    dataset = []
    for line in f:
        if line[0] == '#': #ignore strings that start with "#"
            continue
        sample = line.split(" ")
        c = atoi(sample[-1]) # 取出分类信息
        del sample[-1]
        # 为统一操作，如果样品为第二类，则将所有的属性值乘以-1
        data = []
        for attr in sample:
            if c == -1:
                data.append(-1 * atof(attr))
            else:
                data.append(atof(attr))
        #print(data)
        data.append(c) #转换成增广向量
        dataset.append(data)
    #train the classifier
    PerceptronClassifier(dataset, C)
        

if __name__ == "__main__":
    if _DEBUG == True: 
        import pdb 
        pdb.set_trace()     
    init(sys.argv)
